#include "parser.hpp"
#include <fstream>
#include <string>
#include <vector>

#include <iostream>

void cParser::parse(const char * filename)
{
    questContent = new std::string;
    loadQuest(filename);//cała zawartość questa

    std::string fName;//nazwa funkcji
    int fID;//id funkcji
    qPointer = 0;//wskaznik na aktualnie rozpatrywany znak stringa

    std::vector <std::string> arg;//argumenty funkcji

    //variableParse(questContent);
    //mathParse(questContent);
    //loginParse(questContent);

    while (true)
    {
        //wczytanie nazwy funkcji i zamiana jej na jej identyfikator
        fName = readFunctionName();
        fID = nameToID(fName);

        //pobranie listy argumentow
        switch (fID)
        {
            case FUNC_START: arg = readArguments(1); break;
            case FUNC_EXIT: arg = readArguments(1); break;
            case FUNC_MESSAGE: arg = readArguments(1); break;
        }

        fList.push_back(cFunc(fID, arg));

        //jesli wyszlismy poza zakres stringa to konczymy wczytywanie
        if (qPointer == questContent->length()) break;
    }

    /*for (int i = 0; i < fList.size(); i++)
    {
        std::cout << fList[i].id << " (" << fList[i].arg[0];
        for (int j = 1; j < fList[i].arg.size(); j++)
            std::cout << ", "  << fList[i].arg[j];
        std::cout << ")\n\n";
    }*/
}

void cParser::loadQuest(const char * name)
{
    std::fstream file(name, std::ios::in);
    if (!file) return;

    std::string t;

    while (file >> t)
    {
        questContent[0] += t + " ";
    }
}

const char * cParser::readFunctionName()
{
    std::string s;
    char c;

    while (true)
    {
        c = questContent->at(qPointer++);
        if (c == ' ' || c == ';') break;
        s += c;
    }

    skipWhitespaces();

    return s.c_str();
}

int cParser::nameToID(std::string name)
{
    if (name == "start") return FUNC_START;
    if (name == "exit") return FUNC_EXIT;
    if (name == "message") return FUNC_MESSAGE;

    return -1;
}

std::vector <std::string> cParser::readArguments(int c)
{
    std::vector <std::string> ret;
    std::string s;
    char a;
    bool inQuotes = false;

    //w przypadku 0 argumentów
    if (c == 0)
    {
        return ret;
    }

    for (int i = 0; i < c; i++)
    {
        inQuotes = false;

        a = questContent->at(qPointer++);
        if (a == '"') inQuotes = true;
            s += a;


        while (true)
        {
            a = questContent->at(qPointer++);
            if (a == ',' && !inQuotes) break;
            if (a == ';') break;
            s += a;
        }
        if (a == '"') s.erase(s.size()-1);
        ret.push_back(s);
        skipWhitespaces();
    }

    return ret;
}

void cParser::skipWhitespaces()
{
    char a;
    while (a = questContent->at(qPointer++))
    {
        if (qPointer == questContent->length()) break;
        if (a != 10 && a != 13 && a != ' ')
        {
            qPointer--;
            break;
        }
    }
}
